package org.fatmansoft.teach.service;

import org.apache.poi.ss.formula.functions.T;
import org.fatmansoft.teach.models.*;
import org.fatmansoft.teach.payload.request.DataRequest;
import org.fatmansoft.teach.payload.response.DataResponse;
import org.fatmansoft.teach.repository.*;
import org.fatmansoft.teach.util.CommonMethod;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.relational.core.sql.In;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestBody;

import javax.validation.Valid;
import javax.xml.crypto.Data;
import java.util.*;

@Service
public class CourseService {

    @Autowired
    CourseRepository courseRepository;

    @Autowired
    StudentCourseRepository studentCourseRepository;

    @Autowired
    UserRepository userRepository;

    @Autowired
    StudentRepository studentRepository;
    @Autowired
    TeacherRepository teacherRepository;

    public synchronized Integer getNewCourseId() {
        Integer id = courseRepository.getMaxId();
        if(id == null)
            id = 1;
        else
            id = id +1;
        return id;
    }

    public synchronized Integer getNewStudentCourseId() {
        Integer id = studentCourseRepository.getMaxId();
        if(id == null)
            id = 1;
        else
            id = id + 1;
        return id;
    }

    public Course initCourse() {
        Course course =null;
        Optional<Course> x = courseRepository.findById(1);
        if(x.isPresent()) {
            course = x.get();
        }
        return course;
    }

    public Course findById(Integer id) {
        Course course = null;
        if(id != null) {
            Optional<Course> x = courseRepository.findById(id);
            if(x.isPresent()) {
                course = x.get();
            }
        }
        return course;
    }

    public User getUser(Integer id) {
        User user = null;
        if(id != null) {
            Optional<User> x = userRepository.findById(id);
            if(x.isPresent()) {
                user = x.get();
            }
        }
        return user;
    }

    public Student getStudent(Integer id) {
        Student student = null;
        if(id != null) {
            Optional<Student> x = studentRepository.findById(id);
            if(x.isPresent()) {
                student = x.get();
            }
        }
        return student;
    }

    public Course getCourseByNum(String num) {
        Course course = null;
        if(num != null) {
            Optional<Course> x = courseRepository.findCourseByNum(num);
            if(x.isPresent()) {
                course = x.get();
            }
        }
        return course;
    }

    public Course getCourseByName(String name) {
        Course course = null;
        if(name != null) {
            Optional<Course> x = courseRepository.findCourseByName(name);
            if(x.isPresent()) {
                course = x.get();
            }
        }
        return course;
    }

    public Student getStudentByPersonId(Integer id) {
        Student student = null;
        if(id != null) {
            Optional<Student> x = studentRepository.findByPersonPersonId(id);
            if(x.isPresent()) {
                student = x.get();
            }
        }
        return student;
    }

    public Teacher getTeacherByPersonId(Integer id) {
        Teacher teacher = null;
        if(id != null) {
            Optional<Teacher> x = teacherRepository.findByPersonPersonId(id);
            if(x.isPresent()) {
                teacher = x.get();
            }
        }
        return teacher;
    }

    public StudentCourse getStudentCourseByNum(String studentNum, String courseNum) {
        StudentCourse studentCourse = null;
        if(studentNum != null && courseNum != null) {
            Optional<StudentCourse> x = studentCourseRepository.findByStudentPersonNumAndCourseNum(studentNum, courseNum);
            if(x.isPresent()) {
                studentCourse = x.get();
            }
        }
        return studentCourse;
    }

    public Student getLoginStudent() {
        Integer userId = CommonMethod.getUserId();
        Student student = null;

        User user = getUser(userId);
        if(user != null) {
            Integer personId = user.getPerson().getPersonId();
            student = getStudentByPersonId(personId);
        }

        return student;
    }

    public Teacher getLoginTeacher() {
        Integer userId = CommonMethod.getUserId();
        Teacher teacher = null;
        User user = getUser(userId);
        if(user != null) {
            Integer personId = user.getPerson().getPersonId();
            teacher = getTeacherByPersonId(personId);
        }
        return teacher;
    }

    public Map getMapFromCourse(Course course) {
        Map m = new HashMap();
        if(course == null)
            return m;
        m.put("courseId",course.getCourseId());
        m.put("num",course.getNum());
        m.put("name",course.getName());
        m.put("credit",course.getCredit());
        m.put("bookName",course.getBookName());
        m.put("homework",course.getHomework());
        m.put("material",course.getMaterial());
        m.put("teacher",course.getTeacher().getPerson().getName());
        if(course.getPreCourse() != null)
            m.put("preCourse",course.getPreCourse().getName());

        return m;
    }

    public Map getMapFromStudentCourse(StudentCourse studentCourse) {
        Map m = new HashMap<>();
        m.put("num", studentCourse.getStudent().getPerson().getNum());
        m.put("name",studentCourse.getStudent().getPerson().getName());
        m.put("class",studentCourse.getStudent().getClassName());

        m.put("classNum", studentCourse.getCourse().getNum());
        m.put("credit", studentCourse.getCourse().getCredit());
        m.put("className", studentCourse.getCourse().getName());

        m.put("mark",studentCourse.getMark());

        return m;
    }

    public List getCourseMapList(String numName) {
        List datalist = new ArrayList();
        List<Course> courses = courseRepository.findCourseListByNumName(numName);
        if(courses == null ||courses.size() == 0) {
            return datalist;
        }

        for(int i = 0;i < courses.size();i++) {
            datalist.add(getMapFromCourse(courses.get(i)));
        }
        return datalist;
    }

    public DataResponse saveCourse(DataRequest dataRequest) {

        String num = dataRequest.getString("num");
        String name = dataRequest.getString("name");
        if(name == null)
            return CommonMethod.getReturnMessageError("名称不能为空！");
        if(dataRequest.getString("credit") == null)
            return CommonMethod.getReturnMessageError("学分不能为空！");
        Integer credit = Integer.valueOf(dataRequest.getString("credit"));
        String bookName = dataRequest.getString("bookName");
        String homework = dataRequest.getString("homework");
        String material = dataRequest.getString("material");
        String preCourse = dataRequest.getString("preCourse");
        String teacherNum = dataRequest.getString("teacher");
        Teacher teacher = teacherRepository.findByPersonNum(teacherNum);
        if(teacher == null) {
            return CommonMethod.getReturnMessageError("没有该教师！");
        }

        Course course;

        course = getCourseByNum(num);
        if(course == null) {
            course = new Course();
            course.setCourseId(getNewCourseId());
        }
        course.setNum(num);
        course.setName(name);
        course.setCredit(credit);
        course.setBookName(bookName);
        course.setHomework(homework);
        course.setMaterial(material);
        course.setTeacher(teacher);


        if(!preCourse.equals("")) {
            Course preCourseModel = getCourseByNum(preCourse);
            if(preCourseModel != null)
                course.setPreCourse(preCourseModel);
            else {
                preCourseModel = getCourseByName(preCourse);
                if(preCourseModel != null)
                    course.setPreCourse(preCourseModel);
                else return CommonMethod.getReturnMessageError("没有该前置课程！");
            }
        }

        courseRepository.save(course);

        return CommonMethod.getReturnMessageOK();
    }

    @Transactional
    public DataResponse deleteCourse(DataRequest dataRequest) {
        String num = dataRequest.getString("num");
        if(num.equals(""))
            return CommonMethod.getReturnMessageError("课序号为空！");

        Course course = getCourseByNum(num);
        if(course == null)
            return CommonMethod.getReturnMessageError("没有该课程！");

        courseRepository.deleteByNum(num);

        return CommonMethod.getReturnMessageOK();
    }

    public DataResponse getCourseInfo(DataRequest dataRequest) {
        String num = dataRequest.getString("num");
        Course course = getCourseByNum(num);

        return CommonMethod.getReturnData(getMapFromCourse(course));
    }


    public DataResponse insertStudentCourse(DataRequest dataRequest) {
        Student student = getLoginStudent();
        String num = dataRequest.getString("choseCourse");
        Course course = getCourseByNum(num);
        if(course == null) return CommonMethod.getReturnMessageError("没有该课程！");

        StudentCourse studentCourse = new StudentCourse();
        studentCourse.setStudentCourseId(getNewStudentCourseId());
        studentCourse.setStudent(student);
        studentCourse.setCourse(course);

        studentCourseRepository.save(studentCourse);

        return CommonMethod.getReturnMessageOK();
    }

    @Transactional
    public DataResponse deleteStudentCourse(DataRequest dataRequest) {
        Student student = getLoginStudent();
        String num = dataRequest.getString("choseCourse");
        Course course = getCourseByNum(num);
        if(course == null) return CommonMethod.getReturnMessageError("没有选择该课程！");

        studentCourseRepository.deleteByStudentAndCourse(student, course);

        return CommonMethod.getReturnMessageOK();
    }

    public DataResponse getCourseList(DataRequest dataRequest) {
        String numName = dataRequest.getString("numName");
        List dataList = getCourseMapList(numName);
        return CommonMethod.getReturnData(dataList);
    }

    public DataResponse getNotSelectedCourseList(DataRequest dataRequest) {
        String numName = dataRequest.getString("numName");
        List dataList = new ArrayList();
        Student student = getLoginStudent();

        Set<Course> selectedCourses = null;
        if(!student.getCourses().isEmpty())
            selectedCourses = student.getCourses();
        List<Course> allCourses = courseRepository.findCourseListByNumName(numName);
        List<Course> notSelectedCourses = new ArrayList<>(allCourses);
        if(selectedCourses != null)
            notSelectedCourses.removeAll(selectedCourses);

        for(int i = 0;i < notSelectedCourses.size();i++) {
            dataList.add(getMapFromCourse(notSelectedCourses.get(i)));
        }

        return CommonMethod.getReturnData(dataList);
    }

    public DataResponse getSelectedCourseList(DataRequest dataRequest) {
        List dataList = new ArrayList();
        Student student = getLoginStudent();

        List<Course> selectedCourses = null;
        if(!student.getCourses().isEmpty())
            selectedCourses = new ArrayList<>(student.getCourses());

        if(selectedCourses == null) return CommonMethod.getReturnData(dataList);

        for(int i = 0;i < selectedCourses.size();i++) {
            dataList.add(getMapFromCourse(selectedCourses.get(i)));
        }

        return CommonMethod.getReturnData(dataList);
    }

    public DataResponse getStudentCourseListByLoginStudent(DataRequest dataRequest) {
        Student student = getLoginStudent();
        List dataList = new ArrayList<>();

        List<StudentCourse> sList = studentCourseRepository.findByStudentStudentId(student.getStudentId());
        if(sList == null || sList.size() == 0) return CommonMethod.getReturnData(dataList);

        for(int i = 0;i < sList.size();i++) {
            dataList.add(getMapFromStudentCourse(sList.get(i)));
        }

        return CommonMethod.getReturnData(dataList);
    }

    public DataResponse getSelectedNum(DataRequest dataRequest) {
        Student student = getLoginStudent();
        List<Course> selectedCourse = null;
        if(!student.getCourses().isEmpty())
            selectedCourse = new ArrayList<>(student.getCourses());
        else {
            Integer courseNum = 0;
            Integer creditNum = 0;
            Map<String, Integer> m = new HashMap<>();
            m.put("courseNum",courseNum);
            m.put("creditNum",creditNum);
            return CommonMethod.getReturnData(m);
        }

        Integer courseNum = 0;
        Integer creditNum = 0;
        for(int i = 0;i < selectedCourse.size();i++) {
            creditNum += selectedCourse.get(i).getCredit();
            courseNum += 1;
        }

        Map<String, Integer> m = new HashMap<>();
        m.put("courseNum",courseNum);
        m.put("creditNum",creditNum);

        return CommonMethod.getReturnData(m);
    }

    public DataResponse getLoginTeacherCourse(DataRequest dataRequest) {
        Teacher teacher = getLoginTeacher();
        List dataList = new ArrayList<>();
        List<Course> courseList = courseRepository.findByTeacherTeacherId(teacher.getTeacherId());
        if(courseList == null || courseList.size() == 0)
            return CommonMethod.getReturnData(dataList);
        for(int i = 0;i < courseList.size();i++) {
            dataList.add(getMapFromCourse(courseList.get(i)));
        }
        return CommonMethod.getReturnData(dataList);
    }

    public DataResponse getStudentByCourseNum(DataRequest dataRequest) {
        String num = dataRequest.getString("num");
        List dataList = new ArrayList<>();
        List<StudentCourse> sList = studentCourseRepository.findByCourseNum(num);
        for(int i = 0;i < sList.size();i++) {
            dataList.add(getMapFromStudentCourse(sList.get(i)));
        }
        return CommonMethod.getReturnData(dataList);
    }

    public DataResponse getStudentScore(DataRequest dataRequest) {
        String studentNum = dataRequest.getString("studentNum");
        String courseNum = dataRequest.getString("courseNum");

        StudentCourse studentCourse = getStudentCourseByNum(studentNum, courseNum);
        Map m = new HashMap<>();
        m.put("qizhong",studentCourse.getQizhong());
        m.put("qimo",studentCourse.getQimo());
        m.put("normal",studentCourse.getNormal());
        m.put("mark",studentCourse.getMark());

        return CommonMethod.getReturnData(m);
    }

    public DataResponse saveStudentScore(DataRequest dataRequest) {
        String studentNum = dataRequest.getString("studentNum");
        String courseNum = dataRequest.getString("courseNum");
        StudentCourse studentCourse = getStudentCourseByNum(studentNum, courseNum);
        Integer normal = Integer.parseInt(dataRequest.getString("normal"));
        Integer qizhong = Integer.parseInt(dataRequest.getString("qizhong"));
        Integer qimo = Integer.parseInt(dataRequest.getString("qimo"));
        Double mark = normal*0.3 + qizhong*0.2 + qimo*0.5;

        studentCourse.setNormal(normal);
        studentCourse.setQizhong(qizhong);
        studentCourse.setQimo(qimo);
        studentCourse.setMark(mark);
        studentCourseRepository.save(studentCourse);

        return CommonMethod.getReturnMessageOK();
    }
}
